package com.sangeng.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sangeng.domain.ResponseResult;
import com.sangeng.domain.dto.AddUserDto;
import com.sangeng.domain.dto.UpdateUserDto;
import com.sangeng.domain.entity.User;
import com.sangeng.domain.entity.UserRole;
import com.sangeng.domain.vo.PageVo;
import com.sangeng.domain.vo.UserVo;
import com.sangeng.enums.AppHttpCodeEnum;
import com.sangeng.exception.SystemException;
import com.sangeng.mapper.UserMapper;
import com.sangeng.mapper.UserRoleMapper;
import com.sangeng.service.UserService;
import com.sangeng.utils.BeanCopyUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;
    private final UserRoleMapper userRoleMapper;
    //新增用户

    /**
     * 实际上这个接口有点类似于注册，只不过注册是前台用户操作，现在直接后台操作
     * 数据要求如下：
     * 用户名称不能重复
     * 手机号不能重复
     * 邮箱不能重复
     * 另外，保存密码时，不能保存明文，先加密重新赋值再存入数据库
     */
    @Override
    public ResponseResult<String> addUser(AddUserDto userDto) {
        User user = BeanCopyUtils.copyBean(userDto, User.class);
        //校验
        //非空判断 交给了validation 所以不用再做
        //对数据唯一性进行判断
        if (userNameExist(user.getUserName())) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        if (nickNameExist(user.getNickName())) {
            throw new SystemException(AppHttpCodeEnum.NICKNAME_EXIST);
        }
        if (emailExist(user.getEmail())) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }
        if (phoneNumExist(user.getPhonenumber())) {
            throw new SystemException(AppHttpCodeEnum.PHONENUMBER_EXIST);
        }
        //加密密码
        String encodePassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodePassword);
        save(user);
        //添加完用户之后 取出用户id与角色进行关联 插入user_role关联表
        Long userId = user.getId();
        List<Long> roleIds = userDto.getRoleIds();
//        List<UserRole> userRoles = new ArrayList<>();
        while (!roleIds.isEmpty()) {
            UserRole userRole = new UserRole(userId, roleIds.get(0));
//            userRoles.add(userRole);
            userRoleMapper.insert(userRole);
            roleIds.remove(0);
        }

        return ResponseResult.okResult();
    }

    private boolean userNameExist(String userName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, userName);
        return count(queryWrapper) > 0;//相当于select count
    }

    private boolean nickNameExist(String nickName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNickName, nickName);
        return count(queryWrapper) > 0;//相当于select count
    }

    private boolean emailExist(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email);
        return count(queryWrapper) > 0;//相当于select count
    }

    private boolean phoneNumExist(String phoneNum) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhonenumber, phoneNum);
        return count(wrapper) > 0;
    }

    //修改用户
    @Override
    public ResponseResult<UserVo> getUserById(Long id) {
        User user = userMapper.selectById(id);
        UserVo userVo = BeanCopyUtils.copyBean(user, UserVo.class);
        return ResponseResult.okResult(userVo);
    }

    @Override
    public ResponseResult<String> updateUser(UpdateUserDto userDto) {

        return null;
    }

    //分页（模糊）查询
    @Override
    public ResponseResult<PageVo> getUserByUserName(Integer pageNum, Integer pageSize, String userName, String status) {
        Page<User> userPage = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        //如果没有输入用户名或者没有选择状态，则全部查询 否则模糊查询
        wrapper
                .like(StringUtils.hasText(userName), User::getUserName, userName)
                .like(StringUtils.hasText(status), User::getStatus, status);

        //如果没有后面的查询参数 则纯粹是分页查询
        Page<User> page = page(userPage, wrapper);
        List<User> userList = page.getRecords();
        long total = page.getTotal();
        //打包
        PageVo pageVo = new PageVo(userList, total);
        return ResponseResult.okResult(pageVo);
    }

    //删除
    @Override
    public ResponseResult<String> deleteUserById(List<Long> idList) {
        //逻辑删除
        if (CollectionUtils.isEmpty(idList)) {
            boolean update = lambdaUpdate().set(User::getDelFlag, 1).in(User::getId, idList).update();
            return update ? ResponseResult.okResult() : ResponseResult.errorResult(AppHttpCodeEnum.USER_DELETE_ERROR);
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_ERROR);
    }
}
